/*
 * File:   CalculatorMainWindow.cpp
 * Author: Gab'z
 *
 * Created on 6 juin 2012, 16:35
 */

#include "CalculatorMainWindow.h"
#include "ParametersDialog.h"
#include <QtGui> 
#include "../model/parameters/Parameters.h"

namespace calculator {

    Logger* CalculatorMainWindow::log = LoggerManager::getInstance()->getLogger("CalculatorMainWindow");

    // <editor-fold defaultstate="collapsed" desc="constructeurs et initialisation">

    CalculatorMainWindow::CalculatorMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CalculatorMainWindow) {
        ui->setupUi(this);
        makeConnections();
    }

    CalculatorMainWindow::~CalculatorMainWindow() {
        delete ui;
    }

    void CalculatorMainWindow::updateView() {
        log->trace("updateView... (apply new parameters)");
        try {
            applyViewParameters();
            _tabList->getCurrentTab()->updateObserver();
            updateUndoRedoItemMenu();
            updateStackItemMenu();
        } catch (std::exception& e) {
            log->error(e.what());
        }
        log->trace("updateObserver done");
    }

    void CalculatorMainWindow::updateUndoRedoItemMenu() {
        log->trace("updateUndoRedoItemMenu...");
        ui->menuItemUndo->setEnabled(_engine->getContext()->getMementoCaretaker()->hasPrevious());
        ui->menuItemRedo->setEnabled(_engine->getContext()->getMementoCaretaker()->hasNext());
        log->trace("updateUndoRedoItemMenu done");
    }

    void CalculatorMainWindow::updateStackItemMenu() {
        log->trace("updateStackItemMenu...");
        ui->menuItemDeleteStack->setEnabled(_engine->getContext()->getStackList()->size() > 1);
        log->trace("updateStackItemMenu done");
    }

    void CalculatorMainWindow::init() throw (ViewException) {
        log->trace("Initialization...");
        //hasJustRun = true pour éviter un appel de DUP qui plante au début
        hasJustRun = true;
        if (_engine == 0) throw ViewException("Call setEngine(const Engine* engine) before init()");
        applyViewParameters();
        updateStackItemMenu();
        updateUndoRedoItemMenu();
        _tabList = new StackTabList(_engine);
        initStackTabContainer();
        connect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));
        log->trace("Initialization done");
    }

    void CalculatorMainWindow::initStackTabContainer() {
        log->trace("initStackTabContainer...");
        try {
            for (unsigned int i = 0; i < _tabList->size(); i++) {
                std::ostringstream oss;
                oss << "pile " << i + 1;
                ui->stackTabContainer->addTab(_tabList->getTab(i), QString(oss.str().c_str()));
            }
        } catch (ViewException& e) {
            log->error("Out of stackTabList");
        }
        ui->stackTabContainer->setVisible(true);
        ui->stackTabContainer->setCurrentIndex(_tabList->getCurrentTabIndex());
    }

    void CalculatorMainWindow::prepareForShutdown() {
        disconnect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));
        delete _tabList;
    }

    void CalculatorMainWindow::makeConnections() {
        connect(ui->inputLine, SIGNAL(returnPressed()), this, SLOT(sRun()));
        connect(ui->inputLine, SIGNAL(textEdited()), this, SLOT(sInputLineEdited()));
        connect(ui->run, SIGNAL(clicked()), this, SLOT(sRun()));
        connect(ui->eval, SIGNAL(clicked()), this, SLOT(sEval()));
        connect(ui->raz, SIGNAL(clicked()), ui->inputLine, SLOT(sRaz()));
        connect(ui->numeral0, SIGNAL(clicked()), this, SLOT(s0()));
        connect(ui->numeral1, SIGNAL(clicked()), this, SLOT(s1()));
        connect(ui->numeral2, SIGNAL(clicked()), this, SLOT(s2()));
        connect(ui->numeral3, SIGNAL(clicked()), this, SLOT(s3()));
        connect(ui->numeral4, SIGNAL(clicked()), this, SLOT(s4()));
        connect(ui->numeral5, SIGNAL(clicked()), this, SLOT(s5()));
        connect(ui->numeral6, SIGNAL(clicked()), this, SLOT(s6()));
        connect(ui->numeral7, SIGNAL(clicked()), this, SLOT(s7()));
        connect(ui->numeral8, SIGNAL(clicked()), this, SLOT(s8()));
        connect(ui->numeral9, SIGNAL(clicked()), this, SLOT(s9()));
        connect(ui->add, SIGNAL(clicked()), this, SLOT(sAdd()));
        connect(ui->sub, SIGNAL(clicked()), this, SLOT(sSub()));
        connect(ui->mul, SIGNAL(clicked()), this, SLOT(sMul()));
        connect(ui->div, SIGNAL(clicked()), this, SLOT(sDiv()));
        connect(ui->dot, SIGNAL(clicked()), this, SLOT(sDot()));
        connect(ui->dollar, SIGNAL(clicked()), this, SLOT(sDollar()));
        connect(ui->swap, SIGNAL(clicked()), this, SLOT(sSwap()));
        connect(ui->dup, SIGNAL(clicked()), this, SLOT(sDup()));
        connect(ui->drop, SIGNAL(clicked()), this, SLOT(sDrop()));
        connect(ui->clear, SIGNAL(clicked()), this, SLOT(sClear()));
        connect(ui->mod, SIGNAL(clicked()), this, SLOT(sMod()));
        connect(ui->log, SIGNAL(clicked()), this, SLOT(sLog()));
        connect(ui->cube, SIGNAL(clicked()), this, SLOT(sCube()));
        connect(ui->pow, SIGNAL(clicked()), this, SLOT(sPow()));
        connect(ui->sqrt, SIGNAL(clicked()), this, SLOT(sSqrt()));
        connect(ui->sqr, SIGNAL(clicked()), this, SLOT(sSqr()));
        connect(ui->ln, SIGNAL(clicked()), this, SLOT(sLn()));
        connect(ui->sign, SIGNAL(clicked()), this, SLOT(sSign()));
        connect(ui->fact, SIGNAL(clicked()), this, SLOT(sFact()));
        connect(ui->sinh, SIGNAL(clicked()), this, SLOT(sSinh()));
        connect(ui->cosh, SIGNAL(clicked()), this, SLOT(sCosh()));
        connect(ui->tanh, SIGNAL(clicked()), this, SLOT(sTanh()));
        connect(ui->sin, SIGNAL(clicked()), this, SLOT(sSin()));
        connect(ui->cos, SIGNAL(clicked()), this, SLOT(sCos()));
        connect(ui->tan, SIGNAL(clicked()), this, SLOT(sTan()));
        connect(ui->inv, SIGNAL(clicked()), this, SLOT(sInv()));
        connect(ui->expression, SIGNAL(clicked()), this, SLOT(sExpression()));
        connect(ui->sum, SIGNAL(clicked()), this, SLOT(sSum()));
        connect(ui->mean, SIGNAL(clicked()), this, SLOT(sMean()));
        connect(ui->userCommand, SIGNAL(clicked()), this, SLOT(sUserCommand()));
        connect(ui->space, SIGNAL(clicked()), this, SLOT(sSpace()));
        connect(ui->backSpace, SIGNAL(clicked()), this, SLOT(sBackSpace()));

        // mode
        connect(ui->integerModeRadioButton, SIGNAL(clicked()), this, SLOT(sIntegerMode()));
        connect(ui->rationnalModeRadioButton, SIGNAL(clicked()), this, SLOT(sRationnalMode()));
        connect(ui->realModeRadioButton, SIGNAL(clicked()), this, SLOT(sRealMode()));
        connect(ui->complexModeCheckButton, SIGNAL(clicked()), this, SLOT(sComplexMode()));
        connect(ui->degreeModeRadioButton, SIGNAL(clicked()), this, SLOT(sDegree()));
        connect(ui->radianModeRadioButton, SIGNAL(clicked()), this, SLOT(sRadian()));

        //menu bar
        connect(ui->menuItemSave, SIGNAL(activated()), this, SLOT(sSave()));
        connect(ui->menuItemUndo, SIGNAL(activated()), this, SLOT(sUndo()));
        connect(ui->menuItemRedo, SIGNAL(activated()), this, SLOT(sRedo()));
        connect(ui->menuItemExit, SIGNAL(activated()), this, SLOT(close()));
        connect(ui->menuItemNewStack, SIGNAL(activated()), this, SLOT(sNewStack()));
        connect(ui->menuItemDupStack, SIGNAL(activated()), this, SLOT(sDupStack()));
        connect(ui->menuItemDeleteStack, SIGNAL(activated()), this, SLOT(sRemStack()));
        connect(ui->menuItemParameters, SIGNAL(activated()), this, SLOT(sShowParametersWidget()));
        connect(ui->menuItemShowKeyboard, SIGNAL(activated()), this, SLOT(sShowKeyboard()));
        connect(ui->menuItemHideKeyboard, SIGNAL(activated()), this, SLOT(sHideKeyboard()));
        connect(ui->menuItemHelp, SIGNAL(activated()), this, SLOT(sHelp()));
        connect(ui->menuItemAbout, SIGNAL(activated()), this, SLOT(sAbout()));

    }
    // </editor-fold>

    void CalculatorMainWindow::run(QString input) {
        log->trace("Run input : " + input.toStdString());
        ui->inputLine->setText(input);
        _engine->setInputText(input.toStdString());
        _engine->run();
        if (_engine->getContext()->getError() == true) {
            log->trace("Display error");
            statusBar()->showMessage("Erreur de saisie", 5000);
        }
        hasJustRun = true;
        ui->inputLine->selectAll();
        ui->inputLine->setFocus();
        if (_engine->getContext()->getError()) {
            ui->inputLine->setText(QString(_engine->getContext()->getInputString().c_str()));
        }
        updateUndoRedoItemMenu();
        updateStackItemMenu();
        updateTabName();
    }

    void CalculatorMainWindow::applyViewParameters() {
        log->trace("Applying parameters...");
        Parameters * const parameters = _engine->getContext()->getParameters();
        // <editor-fold defaultstate="collapsed" desc="COMPLEX MODE">
        ui->complexModeCheckButton->setChecked(parameters->getComplexMode());
        // </editor-fold>

        // <editor-fold defaultstate="collapsed" desc="ANGLE UNIT">
        switch (parameters->getAngleUnit()) {
            case calculator::Parameters::DEGREE:
            {
                ui->degreeModeRadioButton->setChecked(true);
                break;
            }
            case calculator::Parameters::RADIAN:
            {
                ui->radianModeRadioButton->setChecked(true);
                break;
            }
            default:
            {
                //cocher Degree par défaut
                ui->degreeModeRadioButton->setChecked(true);
                break;
            }
        }// </editor-fold>

        // <editor-fold defaultstate="collapsed" desc="CONSTANT TYPE">
        switch (parameters->getConstantType()) {
            case calculator::Parameters::INTEGER:
            {
                ui->integerModeRadioButton->setChecked(true);
                break;
            }
            case calculator::Parameters::RATIONNAL:
            {
                ui->rationnalModeRadioButton->setChecked(true);
                break;
            }
            case calculator::Parameters::REAL:
            {
                ui->realModeRadioButton->setChecked(true);
                break;
            }
            default:
            {
                //cocher Integer par défaut
                ui->integerModeRadioButton->setChecked(true);

                break;
            }
        }// </editor-fold>

        ui->menuItemShowKeyboard->setVisible(!parameters->getDisplayKeyboard());
        ui->menuItemHideKeyboard->setVisible(parameters->getDisplayKeyboard());
        ui->keyboardDisplay->setVisible(parameters->getDisplayKeyboard());
        ui->inputLine->setFocus();
        log->trace("Applying parameters done");
    }

    // <editor-fold defaultstate="collapsed" desc="SLOTS">

    void CalculatorMainWindow::sNumeralButton(const std::string str) {
        log->trace("Chiffre : " + str);
        QString input = ui->inputLine->text();
        if (hasJustRun) {
            log->trace("Chiffre : " + str + " nettoyage ligne");
            input.clear();
            input.append(str.c_str());
        } else {
            log->trace("Chiffre : " + str + " -> nombre");
            if (input.length() > 0
                    && (input[input.length() - 1] < '0' || input[input.length() - 1] > '9')
                    && (input[input.length() - 1] != '/' && input[input.length() - 1] != '$')) {
                input.append(" ");
            }
            input.append(str.c_str());
        }

        ui->inputLine->setText(input);
        hasJustRun = false;
        ui->inputLine->setFocus();
    }

    void CalculatorMainWindow::sTextButton(const std::string str) {
        log->trace("Commande : " + str);

        QString input = ui->inputLine->text();
        // si instant Compute alors on remplace
        //      si un nombre est déjà là il faut l'executer avant 
        //      sauf s'il vient d'être executé
        // sinon on ajoute 
        if (_engine->getContext()->getParameters()->getInstantCompute()) {
            log->trace("instantCompute = ON");
            if (!hasJustRun) {
                log->trace("Command : run previous input");
                run(input);
            }
            input.clear();
            input.append(str.c_str());
            log->trace("Command : run input");
            run(input);
        } else {
            log->trace("instantCompute = OFF");
            input.append(" ");
            input.append(str.c_str());
            ui->inputLine->setText(input);
        }
    }

    void CalculatorMainWindow::sInputLineEdited() {
        log->trace("hasJustRun = false");
        hasJustRun = false;
    }

    // <editor-fold defaultstate="collapsed" desc="SLOTS CLAVIER">

    void CalculatorMainWindow::sRun() {
        run(ui->inputLine->text());
    }

    void CalculatorMainWindow::s0() {
        sNumeralButton("0");
    }

    void CalculatorMainWindow::s1() {
        sNumeralButton("1");
    }

    void CalculatorMainWindow::s2() {
        sNumeralButton("2");
    }

    void CalculatorMainWindow::s3() {
        sNumeralButton("3");
    }

    void CalculatorMainWindow::s4() {
        sNumeralButton("4");
    }

    void CalculatorMainWindow::s5() {
        sNumeralButton("5");
    }

    void CalculatorMainWindow::s6() {
        sNumeralButton("6");
    }

    void CalculatorMainWindow::s7() {
        sNumeralButton("7");
    }

    void CalculatorMainWindow::s8() {
        sNumeralButton("8");
    }

    void CalculatorMainWindow::s9() {
        sNumeralButton("9");
    }

    void CalculatorMainWindow::sDot() {
        sNumeralButton(".");
    }

    void CalculatorMainWindow::sDollar() {
        sNumeralButton("$");
    }

    void CalculatorMainWindow::sAdd() {
        sTextButton("+");
    }

    void CalculatorMainWindow::sSub() {
        sTextButton("-");
    }

    void CalculatorMainWindow::sMul() {
        sTextButton("*");
    }

    void CalculatorMainWindow::sDiv() {
        // comportement particulier de la touche '/'
        // si collé contre un chiffre ==> début d'un rationnel
        // si un espace avant, opérateur '/'
        QString input = ui->inputLine->text();
        if (input.length() == 0
                || (input.length() == 1 && input[input.length() - 1] == '/')
                || (input.length() != 0 && input[input.length() - 1] == ' ')) sTextButton("/");
        else sNumeralButton("/");
    }

    void CalculatorMainWindow::sEval() {
        sTextButton("EVAL");
    }

    void CalculatorMainWindow::sSwap() {
        sTextButton("SWAP");
    }

    void CalculatorMainWindow::sDup() {
        sTextButton("DUP");
    }

    void CalculatorMainWindow::sDrop() {
        sTextButton("DROP");
    }

    void CalculatorMainWindow::sClear() {
        sTextButton("CLEAR");
    }

    void CalculatorMainWindow::sMod() {
        sTextButton("MOD");
    }

    void CalculatorMainWindow::sLog() {
        sTextButton("LOG");
    }

    void CalculatorMainWindow::sFact() {
        sTextButton("FACT");
    }

    void CalculatorMainWindow::sCube() {
        sTextButton("CUBE");
    }

    void CalculatorMainWindow::sPow() {
        sTextButton("POW");
    }

    void CalculatorMainWindow::sSqrt() {
        sTextButton("SQRT");
    }

    void CalculatorMainWindow::sSqr() {
        sTextButton("SQR");
    }

    void CalculatorMainWindow::sLn() {
        sTextButton("LN");
    }

    void CalculatorMainWindow::sSign() {
        sTextButton("SIGN");
    }

    void CalculatorMainWindow::sSin() {
        sTextButton("SIN");
    }

    void CalculatorMainWindow::sCos() {
        sTextButton("COS");
    }

    void CalculatorMainWindow::sTan() {
        sTextButton("TAN");
    }

    void CalculatorMainWindow::sSinh() {
        sTextButton("SINH");
    }

    void CalculatorMainWindow::sCosh() {
        sTextButton("COSH");
    }

    void CalculatorMainWindow::sTanh() {
        sTextButton("TANH");
    }

    void CalculatorMainWindow::sInv() {
        sTextButton("INV");
    }

    void CalculatorMainWindow::sExpression() {
        sTextButton("\'");
    }

    void CalculatorMainWindow::sSum() {
        sTextButton("SUM");
    }

    void CalculatorMainWindow::sMean() {
        sTextButton("MEAN");
    }

    void CalculatorMainWindow::sUserCommand() {
        log->error("UserCommand not yet implemented");
        // sTextButton("\\");
    }

    void CalculatorMainWindow::sSpace() {
        sTextButton("");
    }

    void CalculatorMainWindow::sRaz() {
        ui->inputLine->clear();
    }

    void CalculatorMainWindow::sBackSpace() {
        QString input = ui->inputLine->text();
        if (input.length() == 0) {

        } else {
            input.truncate(input.length() - 1);
            ui->inputLine->setText(input);
        }

    }// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SLOTS MODE">

    void CalculatorMainWindow::sIntegerMode() {
        _engine->setConstantTypeTo("INT");
    }

    void CalculatorMainWindow::sRationnalMode() {
        _engine->setConstantTypeTo("RAT");
    }

    void CalculatorMainWindow::sRealMode() {
        _engine->setConstantTypeTo("REAL");
    }

    void CalculatorMainWindow::sComplexMode() {
        _engine->switchComplexMode();
    }

    void CalculatorMainWindow::sDegree() {
        _engine->setAngleUnitTo("DEG");
    }

    void CalculatorMainWindow::sRadian() {
        _engine->setAngleUnitTo("RAD");
    }// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SLOTS UNDO/REDO">

    void CalculatorMainWindow::sUndo() {
        log->trace("UNDO");
        disconnect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));
        ui->stackTabContainer->clear();
        delete _tabList;

        _engine->undo();

        _tabList = new StackTabList(_engine);
        initStackTabContainer();
        ui->stackTabContainer->setCurrentIndex(_tabList->getCurrentTabIndex());
        connect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));
        hasJustRun = true;
        updateUndoRedoItemMenu();
        updateStackItemMenu();
        ui->stackTabContainer->setVisible(true);

        std::cout.flush();
    }

    void CalculatorMainWindow::sRedo() {
        log->trace("REDO");

        disconnect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));
        ui->stackTabContainer->clear();
        delete _tabList;

        _engine->redo();

        _tabList = new StackTabList(_engine);
        initStackTabContainer();
        ui->stackTabContainer->setCurrentIndex(_tabList->getCurrentTabIndex());
        connect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));
        hasJustRun = true;
        updateUndoRedoItemMenu();
        updateStackItemMenu();
        ui->stackTabContainer->setVisible(true);

        std::cout.flush();
    }// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SLOTS PILES">

    void CalculatorMainWindow::sNewStack() {
        //        log->trace("SNEW");
        //        std::ostringstream oss;
        //        oss << "Current index = " << ui->stackTabContainer->currentIndex();
        //        log->trace(oss.str());
        _engine->newStack();
        _tabList->newTab();
        std::ostringstream oss2;
        oss2 << "pile " << _tabList->getCurrentTabIndex() + 1;
        disconnect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));

        ui->stackTabContainer->addTab(_tabList->getCurrentTab(), QString(oss2.str().c_str()));
        ui->stackTabContainer->setCurrentIndex(_tabList->getCurrentTabIndex());
        connect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));

        updateUndoRedoItemMenu();
        updateStackItemMenu();
        std::cout.flush();
    }

    void CalculatorMainWindow::sDupStack() {
        log->trace("SDUP");
        //        std::ostringstream oss;
        //        oss << "Current index of container = " << ui->stackTabContainer->currentIndex();
        //        log->trace(oss.str());

        _engine->dupStack();
        // maj de l'interface
        _tabList->duplicateCurrentTab();
        std::ostringstream oss2;
        oss2 << "pile " << _tabList->getCurrentTabIndex() + 1;
        disconnect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));
        ui->stackTabContainer->insertTab(ui->stackTabContainer->currentIndex() + 1,
                _tabList->getCurrentTab(), QString(oss2.str().c_str()));

        _tabList->getCurrentTab()->updateObserver();
        ui->stackTabContainer->setCurrentIndex(_tabList->getCurrentTabIndex());
        connect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));

        updateUndoRedoItemMenu();
        updateStackItemMenu();
        updateTabName();
        std::cout.flush();
    }

    void CalculatorMainWindow::sRemStack() {
        log->trace("SREM");
        //        std::ostringstream oss;
        //        oss << "Current index of container = " << ui->stackTabContainer->currentIndex();
        //        log->trace(oss.str());

        disconnect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));
        ui->stackTabContainer->removeTab(ui->stackTabContainer->currentIndex());
        connect(ui->stackTabContainer, SIGNAL(currentChanged(int)), this, SLOT(sSwitchStack(int)));

        _tabList->removeCurrentTab();
        _engine->removeCurrentStack();
        updateUndoRedoItemMenu();
        updateStackItemMenu();
        updateTabName();
        std::cout.flush();
    }

    void CalculatorMainWindow::sSwitchStack(int index) {
        log->trace("SWITCH");
        // appelé lors d'un clic sur un onglet
        _engine->setCurrentStack(index);
        _tabList->setCurrentTab(index);

    }

    void CalculatorMainWindow::updateTabName() {
        log->trace("updateTabName");
        for (int i = ui->stackTabContainer->currentIndex(); i < ui->stackTabContainer->count(); i++) {
            std::ostringstream oss;
            oss << "pile " << i + 1;
            ui->stackTabContainer->setTabText(i, QString(oss.str().c_str()));
        }
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="SLOTS INTERFACE">

    void CalculatorMainWindow::sShowKeyboard() {
        _engine->getContext()->getParameters()->setDisplayKeyboard(true);
        ui->menuItemShowKeyboard->setVisible(false);
        ui->menuItemHideKeyboard->setVisible(true);
        ui->keyboardDisplay->setVisible(true);
    }

    void CalculatorMainWindow::sHideKeyboard() {
        _engine->getContext()->getParameters()->setDisplayKeyboard(false);
        ui->menuItemShowKeyboard->setVisible(true);
        ui->menuItemHideKeyboard->setVisible(false);
        ui->keyboardDisplay->setVisible(false);
    }

    void CalculatorMainWindow::sShowParametersWidget() {
        ParametersDialog* dialog = new ParametersDialog(_engine, this);
        dialog->setVisible(true);
        dialog->exec();
        delete dialog;
        updateView();
    }

    void CalculatorMainWindow::sAbout() {

        QMessageBox::about(this, tr("A propos"),
                tr("Cette <b>Calculatrice</b> a été réalisée dans le cadre de "
                "l'UV de programmation orientée objet LO21 à l'UTC "
                "par les étudiants Arnaud Schwartz et Ran Zhao"));
    }

    void CalculatorMainWindow::sHelp() {

    }

    void CalculatorMainWindow::sSave() {
        log->trace("Saving context...");
        _engine->getContext()->saveContextToXML();
        log->trace("Saving context done");
    }// </editor-fold>

    // </editor-fold>
}
